<script setup>
const props = defineProps({
  width: {
    type: String,
    default: '800px',
  },
  title: {
    type: String,
    default: '',
  },
  closable: {
    type: Boolean,
    default: true,
  },
  cancelText: {
    type: String,
    default: '取消',
  },
  okText: {
    type: String,
    default: '确定',
  },
  showHeader: {
    type: Boolean,
    default: true,
  },
  showFooter: {
    type: Boolean,
    default: true,
  },
  showCancel: {
    type: Boolean,
    default: true,
  },
  showOk: {
    type: Boolean,
    default: true,
  },
  modalStyle: {
    type: Object,
    default: () => {},
  },
  onOk: {
    type: Function,
    default: () => {},
  },
  onCancel: {
    type: Function,
    default: () => {},
  },
})

const dialogRef = ref(null)
// 声明一个show变量，用于控制模态框的显示与隐藏
const show = ref(false)

// 定义一个close函数，用于关闭模态框
function close() {
  show.value = false
}

// 声明一个modalOptions变量，用于存储模态框的配置信息
const modalOptions = ref({})

const okLoading = computed({
  get() {
    return !!modalOptions.value?.okLoading
  },
  set(v) {
    if (modalOptions.value) {
      modalOptions.value.okLoading = v
    }
  },
})

// 定义一个handleOk函数，用于处理模态框确定操作
async function handleOk(data) {
  // 如果modalOptions中没有onOk函数，则直接关闭模态框
  if (typeof modalOptions.value.onOk !== 'function') {
    return close()
  }
  try {
    // 调用onOk函数，传入data参数
    const res = await modalOptions.value.onOk(data)
    // 如果onOk函数的返回值不为false，则关闭模态框
    if (res !== false)
      close()
  }
  catch (error) {
    console.error(error)
    okLoading.value = false
  }
}

// 定义一个handleCancel函数，用于处理模态框取消操作
async function handleCancel(data) {
  // 如果modalOptions中没有onCancel函数，则直接关闭模态框
  if (typeof modalOptions.value.onCancel !== 'function') {
    return close()
  }
  try {
    // 调用onCancel函数，传入data参数
    const res = await modalOptions.value.onCancel(data)
    // 如果onCancel函数的返回值不为false，则关闭模态框
    if (res !== false)
      close()
  }
  catch (error) {
    console.error(error)
    okLoading.value = false
  }
}

// 打开模态框
async function open(options = {}) {
  // 将props和options合并赋值给modalOptions
  modalOptions.value = { ...props, ...options }
  // 将show的值设置为true
  show.value = true
  await nextTick()
  dialogRef.value?.resetPosition()
}

// 定义一个defineExpose函数，用于暴露open、close、handleOk、handleCancel函数
defineExpose({
  open,
  close,
  handleOk,
  handleCancel,
  okLoading,
  options: modalOptions,
})
</script>

<template>
  <el-dialog
    ref="dialogRef"
    v-model="show"
    draggable
    center
    :style="{ width: modalOptions.width, ...modalOptions.modalStyle }"
    :close-on-press-escape="false"
    :close-on-click-modal="false"
    align-center
    :show-close="closable"
    @close="close()"
  >
    <template #header>
      <slot v-if="$slots.header" name="header" />
      <header v-else-if="modalOptions.showHeader">
        {{ modalOptions.title }}
      </header>
    </template>
    <slot />
    <!-- 底部按钮 -->
    <template #footer>
      <slot v-if="$slots.footer" name="footer" />
      <footer v-else-if="modalOptions.showFooter" class="flex justify-end">
        <el-button v-if="modalOptions.showCancel" @click="handleCancel()">
          {{ modalOptions.cancelText }}
        </el-button>
        <el-button
          v-if="modalOptions.showOk"
          type="primary"
          :loading="modalOptions.okLoading"
          class="ml-20"
          @click="handleOk()"
        >
          {{ modalOptions.okText }}
        </el-button>
      </footer>
    </template>
  </el-dialog>
</template>
